# -*- coding: utf-8 -*-

"""
XMLParsing module.

This module is used to parse XML files which contain the data for questions.
It uses the SAX (Simple API for XML) module.

Tag definitions:
<q> - Main question tag. Has two attributes; question and answer.
<tussenstap> - Single-tag. Has two attributes; stap and stapanswer
<figure> - Everything inside this tag will be interpreted as one figure. Has no attributes.
<point> - This defines a point. The data between the opening and closing tag are the coordinates for that point. Has two attributes; name and align.
<line> - This defines a line. The data between the opening and closing tag are the names of the beginning point and the end point of the line. Has two attributes; length and align. 
<pixelpoint> - This defines a point in pixels. The data between the opening and closing tag are the coordinates in pixels. Has two attributes; name and align.
<legendinfo> - This defines additional info for display in the legenda. For now this is used to show angles.

Handy XML entities:
&#xA; - Newline
&#8730; - Square root
&#176; - Degree sign
&#8736; - Angle 
"""

from xml.sax import make_parser
from xml.sax import saxutils
from xml.sax.handler import feature_namespaces

class ParseQuestions(saxutils.DefaultHandler):
    """
    The main class for XMLParsing.
    startElement() gets called each time a new tag is found.
    It then chechks which tag we're dealing with and puts the data in the new question dictionary.
    When endElement gets called with q as the name attribute, the new question is finished and the new question
    is appended to the main questions array.
    """
    def __init__(self):
        self.questions = []
        self.tussenstap, self.tussenstapanswer = "", ""
        self.inPointContent, self.fig = 0, 0
        
    def startElement(self, name, attrs):
        if name == 'q':
            self.newq = {'question' : "", 'answer' : "", 'tussenstap' : [], 'tussenstapanswer' : [], 'geometry' : {'figures' : [], 'lines': [], 'legendinfo': []}}
            self.newq['question'] = attrs.get('question', None)
        if name == 'tussenstap':
            self.tussenstap = attrs.get('stap', None)
            self.tussenstapanswer = attrs.get('stapanswer', None)
        if name == 'figure':
            self.fig += 1
            self.newq['geometry']['figures'].append({'points' : [], 'lines' : [], 'pixelpoints' : []})
        if name == 'point' or name == 'pixelpoint':
            self.newpoint = {'name' : "", 'x' : "", 'y' : "", 'align' : ""}
            self.inPointContent = 1
            self.newpoint['name'] = attrs.get('name', None)
            self.newpoint['align'] = attrs.get('align', None)
            self.newcoord = ""
        if name == 'line':
            self.newline = {'length' : "", 'p1' : "", 'p2' : "", 'align' : ""}
            self.inPointContent = 1
            self.newline['length'] = attrs.get('length', None)
            self.newline['align'] = attrs.get('align', None)
            self.newcoord = ""
        if name == 'legendinfo':
            self.legendinfo = attrs.get('info', None)
    
    def characters(self, ch):
        if self.inPointContent:
            self.newcoord += ch
            
    def endElement(self, name):
        if name == 'q':
            self.questions.append(self.newq)
            self.fig=0

        if name == 'tussenstap':
            self.newq['tussenstap'].append(self.tussenstap)
            self.newq['tussenstapanswer'].append(self.tussenstapanswer)

        if name == 'point':
            x = self.newcoord.split(",")[0]
            y = self.newcoord.split(",")[1]
            self.newpoint['x'] = x
            self.newpoint['y'] = y
            self.newq['geometry']['figures'][self.fig-1]['points'].append(self.newpoint)
            self.inPointContent = 0
            self.newpoint = ""

        if name == 'pixelpoint':
            x = self.newcoord.split(",")[0]
            y = self.newcoord.split(",")[1]
            self.newpoint['x'] = x
            self.newpoint['y'] = y
            self.newq['geometry']['figures'][self.fig-1]['pixelpoints'].append(self.newpoint)
            self.inPointContent = 0
            self.newpoint = ""
        
        if name == 'line':
            p1 = self.newcoord.split(",")[0]
            p2 = self.newcoord.split(",")[1]
            self.newline['p1'] = p1
            self.newline['p2'] = p2
            self.newq['geometry']['lines'].append(self.newline)
            self.inPointContent = 0
            self.newline = ""
        
        if name == 'legendinfo':
            self.newq['geometry']['legendinfo'].append(self.legendinfo)
            
def parseQuestionFile(qfile):
    """
    This function parses an XML file using the ParseQuestion class.
    Then it returns the questions array back to main.py
    """
    parser = make_parser()
    parser.setFeature(feature_namespaces, 0)
    dh = ParseQuestions()
    parser.setContentHandler(dh)
    parser.parse(qfile)
    return dh.questions
